package com.ilvyou.api.service;

import com.ilvyou.api.common.Constant;
import com.ilvyou.api.util.LhfUtil;
import com.ilvyou.api.util.RemoteUtil;
import com.ilvyou.core.base.BaseService;
import com.ilvyou.core.dao.Criteria;
import com.ilvyou.core.dao.Dao;
import com.ilvyou.core.util.StringUtil;
import com.ilvyou.core.util.Util;
import com.ilvyou.data.lhf.*;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by GuanYuCai on 2016/9/6 0006.
 */
@Service
public class UserService extends BaseService {

    @Resource(name = "lhfDao")
    private Dao lhfDao;
    @Autowired
    private ZanService systemService;

    @Override
    protected Dao getDao() {
        return lhfDao;
    }

    public ScrAlipayEntity getScrAlipayEntityByAccount(String account) throws Exception {
        Criteria criteria = new Criteria().add("actname=? or mobile=? or email=?", account, account, account);
        return lhfDao.get(ScrAlipayEntity.class, criteria);
    }

    public boolean checkPassword(ScrAlipayEntity entity, String password) throws Exception {
        if (entity == null) { //用户名不正确或用户不可用
            return false;
        } else {
            password = StringUtil.base64Decode(password);
            //调用远程接口验证密码是否正确
            String pwd = RemoteUtil.getMd5Pwd(password, entity.getSalt());
            return entity.getPassword().equals(pwd);
        }
    }

    public boolean isCompleteInfo(long actId) throws Exception {
        if (lhfDao.get(ScrAnswerEntity.class, new Criteria().add("actid=?", actId)) != null) {
            AlipayAccountEntity alipay = lhfDao.get(AlipayAccountEntity.class,
                    new Criteria().add("actid=?", actId));
            if (alipay != null && !StringUtil.isEmpty(alipay.getPaypassword())) {
                return true;
            }
        }

        return false;
    }

    public long sendSms(String phone, int type) throws IllegalAccessException {
        String msg = "";
        String createdName = Constant.sms.get(type);
        if (createdName == null){
            createdName = "";
        }

        Date date = new Date();
        String dateStr = LhfUtil.toStr(date, "yyyy-MM-dd HH:mm:ss");
        String code = StringUtil.randomNum(6);


        if (type == Constant.SMSType.BIND_MOBILE || type == Constant.SMSType.UNBIND_MOBILE){
            msg = "尊敬的用户：您好，您于" + dateStr + "进行" + createdName + "操作，短信验证码：" + code + "，15分钟内有效，如非本人操作，请及时致电400-114-6969！【乐汇付】—";
        }else{
            msg = "尊敬的用户：您好，您于" + dateStr + "进行" + createdName + "操作，短信验证码：" + code + "，15分钟内有效，如非本人操作，请忽略此短信！【乐汇付】—";
        }

        // 发送短信
        try {
            RemoteUtil.sendSMS(phone, msg);
        } catch (Exception e) {
            log.warn("send sms fail!", e);
            return 0;
        }

        // 写数据库
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        cld.add(Calendar.MINUTE, 15);
        long sendId = Long.parseLong(StringUtil.randomNum(10));

        ScrPhoneEntity a = new ScrPhoneEntity();
        a.setSendid(sendId);
        a.setSenddate(new Timestamp(date.getTime()));
        a.setMobile(phone);
        a.setSendcode(code);
        a.setSendtype((short) type);
        a.setEffecminutes(15);
        a.setEnddate(new Timestamp(cld.getTimeInMillis()));
        a.setSenddetails(msg);
        a.setCreatedname(createdName);
        a.setCreatedby(0l);
        addSms(a);

        return sendId;
    }

    public boolean verifySmsCode(long sendId, String sendCode, String mobile, int type) throws Exception{
        return getSmsDeadline(sendId, sendCode, mobile, type) > System.currentTimeMillis();
    }

    public long getSmsDeadline(long sendId, String sendCode, String mobile, int type) throws Exception {
        ScrPhoneEntity phoneEntity = lhfDao.get(ScrPhoneEntity.class,
                new Criteria().add("sendid=?", sendId));
        return phoneEntity != null
                && phoneEntity.getSendcode().equals(sendCode)
                && mobile.equals(phoneEntity.getMobile())
                && phoneEntity.getSendtype() == type
                && phoneEntity.getEnddate().after(new Date()) ? phoneEntity.getEnddate().getTime() : 0;
    }

    public void updatePassword(String mobile, String password) throws Exception{
        ScrAlipayEntity alipay = getScrAlipayEntityByAccount(mobile);
        if (alipay != null){
            password = StringUtil.base64Decode(password);
            password = RemoteUtil.getMd5Pwd(password, alipay.getSalt());
            alipay.setPassword(password);
            lhfDao.update(alipay);
        }
    }

    public ScrAlipayEntity addUser(String mobile, String password) throws Exception{
        ScrAlipayEntity scrAlipay = getScrAlipayEntityByAccount(mobile);  //根据手机号查询用户是否存在

        if (scrAlipay != null && scrAlipay.getEnableflag() != 0){
            return null;
        }

        //Base64解密 密码字符串
        String salt = StringUtil.UUID();
        password = RemoteUtil.getMd5Pwd(password, salt);  //获得加密后的登录密码

        if(scrAlipay == null){  //用户不存在，插入数据库
            //获取actName
            String actName = systemService.getSequenceName("SRC_ALIPAY", "ACTNAME");
            //获取账户Id
            long actId = Util.createId();

            //插入数据到数据库  scr_alipay(帐号-乐付宝)
            scrAlipay = insertAlipay(actId, actName, salt, password, mobile);

            int periodbeginday = LhfUtil.getPeriodBeginDay();  //账单开始日
            int periodendday = LhfUtil.getPeriodEndDay();      //账单结束日
            //插入数据到数据库  alipay_account(乐付宝-账户)
            insertAlipayAccount(actId, actName, periodbeginday, periodendday);

            //插入数据到数据库credit_account(乐信宝-账户)
            insertCreditAccount(actId, actName, periodbeginday, periodendday);

            //插入数据到数据库  alipay_period(乐付宝-账期)
            long periodId = Util.createId(); //账期Id
            int periodMonth =  LhfUtil.getPeriodMonth();  //账期月份
            insertAlipayPeriod(actId, actName, periodId, periodMonth, periodbeginday + "", periodendday + "");

            //插入数据到数据库  credit_period_head(乐信宝-帐期表)
            insertCreditPeriod(actId, actName, periodId, periodMonth, periodbeginday + "", periodendday + "");
        }else if(scrAlipay.getEnableflag() == 0){ //用户存在但不可用

            //修改用户登录密码
            scrAlipay.setPassword(password);
            scrAlipay.setFaceurl("");
            lhfDao.update(scrAlipay);
        }

        return scrAlipay;
    }

    private void addSms(ScrPhoneEntity a) throws IllegalAccessException {
        lhfDao.insert(a);
    }

    private ScrAlipayEntity insertAlipay(long actId, String actName, String salt, String pwd, String mobile) throws Exception {
        ScrAlipayEntity a = new ScrAlipayEntity();
        a.setActid(actId);
        a.setActname(actName);
        a.setSalt(salt);
        a.setPassword(pwd);
        a.setMobile(mobile);
        a.setCreatedby(actId);
        a.setLastedby(actId);
        a.setIsnew(1);
        a.setEnableflag((short) 0);
        a.setBppagentcategory((short) 0);

        // 数据库字段not null，设个默认值
        a.setIdcardflag((short) 1);
        a.setMobileflag((short) 1);
        a.setEmailflag((short) 0);
        a.setBppuserid(0l);
        a.setBppcompanyid(0l);
        lhfDao.insert(a);

        return a;
    }

    private void insertAlipayAccount(long actId, String actName, int begin, int end) throws Exception {
        AlipayAccountEntity a = new AlipayAccountEntity();
        a.setActid(actId);
        a.setActname(actName);
        a.setPeriodbeginday(begin);
        a.setPeriodendday(end);
        a.setEnableflag((short) 0);
        a.setCreatedby(actId);
        a.setLastedby(actId);
        lhfDao.insert(a);
    }

    private void insertCreditAccount(long actId, String actName, int begin, int end) throws IllegalAccessException {
        CreditAccountEntity a = new CreditAccountEntity();
        a.setActid(actId);
        a.setActname(actName);
        a.setPeriodbeginday(begin);
        a.setPeriodendday(end);
        a.setCreatedby(actId);
        a.setLastedby(actId);
        a.setRepaymentday((short) 10);
        lhfDao.insert(a);
    }

    private void insertCreditPeriod(long actId, String actName, long periodId,
                           int periodMonth, String beginDay, String endDay)
            throws Exception {
        CreditPeriodHeadEntity a = new CreditPeriodHeadEntity();
        a.setActid(actId);
        a.setActname(actName);
        a.setPeriodid(periodId);
        a.setPeriodmonth(periodMonth);
        a.setPeriodbegindate(beginDay);
        a.setPeriodenddate(endDay);
        a.setRepaymentdate(LhfUtil.toStr(new Date(), "yyyyMMdd")); //暂时设定为当前日期，后期再修改
        a.setPeriodflag((short) 1);
        a.setCurrentflag((short) 1);
        a.setCreatedname(actName);
        a.setCreatedby(actId);
        a.setLastedname(actName);
        a.setLastedby(actId);
        lhfDao.insert(a);
    }

    private void insertAlipayPeriod(long actId, String actName, long periodId,
                           int periodMonth, String beginDay, String endDay)
            throws Exception {
        AlipayPeriodEntity a = new AlipayPeriodEntity();
        a.setActid(actId);
        a.setActname(actName);
        a.setPeriodid(periodId);
        a.setPeriodmonth(periodMonth);
        a.setPeriodbegindate(beginDay);
        a.setPeriodenddate(endDay);
        a.setCreatedby(actId);
        a.setLastedby(actId);
        a.setCurrentflag((short) 1);
        lhfDao.insert(a);
    }
}
